package com.jee.ssm.modules.hikBill.app;

import java.math.BigDecimal;
import java.util.Date;
import java.util.List;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;

import org.apache.log4j.Logger;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.domain.AlipayTradeAppPayModel;
import com.alipay.api.request.AlipayTradeAppPayRequest;
import com.alipay.api.response.AlipayTradeAppPayResponse;
import com.jee.ssm.common.config.ShopInfo;
import com.jee.ssm.common.utils.CalculateUtils;
import com.jee.ssm.common.utils.TimeUtils;
import com.jee.ssm.common.utils.TokenUtils;
import com.jee.ssm.common.utils.UUIDFactory;
import com.jee.ssm.common.utils.hik.HikUtils;
import com.jee.ssm.common.utils.wechat.PaymaxConfig;
import com.jee.ssm.common.utils.wechat.RandCharsUtils;
import com.jee.ssm.common.utils.wechat.Unifiedorder;
import com.jee.ssm.common.utils.wechat.WXPay;
import com.jee.ssm.model.BillRecord;
import com.jee.ssm.model.User;
import com.jee.ssm.model.hik.ChargeRecord;
import com.jee.ssm.model.hik.receive.HikBill;
import com.jee.ssm.model.json.Tip;
import com.jee.ssm.modules.billRecord.services.BillRecordService;
import com.jee.ssm.modules.hikBill.services.HikBillService;
import com.jee.ssm.modules.user.services.UserService;

/**
* 海康账单记录管理 客户端 Controller
* @author GaoXiang
* @version 1.0
*/
@Controller
@RequestMapping("/app/hikBill")
public class AppHikBillController {

	private Logger logger = Logger.getLogger(AppHikBillController.class);

	@RequestMapping(value = "/editHikBill")
	@ResponseBody
	public Tip editHikBill(Integer day, Integer hour) {
		long start = System.currentTimeMillis();
		Tip tip = new Tip();
		HikBill hikBill = new HikBill();
		hikBill.setPayStatus(0);
		Date createTime;
		if(day != null) {
			createTime = TimeUtils.getWantedDateWithoutOmit(day);
		} else if(hour != null) {
			createTime = TimeUtils.getWantedHourWithoutOmit(hour);
		} else {
			createTime = TimeUtils.getWantedDateWithoutOmit(-1000);
		}
		hikBill.setCreateTime(createTime);
		List<HikBill> list = hikBillService.findByPayStatus(hikBill);
		logger.info("查询到的未支付的数据为" + list.size() + "条");
		int a = 0, b = 0, c = 0;
		for(HikBill hb : list) {
			List<ChargeRecord> crs = HikUtils.getChargeByPlateNo(hb.getCreateTime().getTime() - 864000000, hb.getCreateTime().getTime(), hb.getParkCode(), hb.getPlateNo(), hb.getPlateColor());
			logger.info("---------------" + hb.getPlateNo() + "-----------------");
			for(ChargeRecord cr : crs) {
				c ++;
				if(hb.getInTime().longValue() == cr.getInTime().longValue()) {
					hb.setUpdateTime(new Date());
					hb.setPayStatus(1);
					hb.setPayMethod(0);
					try {
						hikBillService.updateById(hb);
						a ++;
					} catch (Exception e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
						b ++;
					}
					break;
				}
			}
		}
		long end = System.currentTimeMillis();
		String data = "修改账单耗时：" + TimeUtils.formatTime(end - start) + "；可被修改：" + c + "条；修改成功：" + a + "条；修改失败：" + b + "条";
		logger.info(data);
		tip.setData(data);
		return tip;
	}

	/**
	 * 查询账单列表
	 * @param userId 用户标识
	 * @return
	 */
	@RequestMapping(value = "/findHikBillByUserId", method = RequestMethod.GET)
	@ResponseBody
	public Tip findHikBillByUserId(long timestamp, String token, String userId, String payStatus) {
		Tip tip = TokenUtils.verifyToken(timestamp, token);
		if(tip.getSuccess()) {
			User user = userService.selectById(userId);
			if(user != null) {
				HikBill hb = new HikBill();
				if(payStatus != null && !"".equals(payStatus)) {
					hb.setPayStatus(Integer.valueOf(payStatus));
				}
				hb.setUserId(userId);
				List<HikBill> list = hikBillService.findByPayStatus(hb);
				tip = new Tip(list);
			} else {
				tip = new Tip(1, "未查找该用户");
			}
		}
		return tip;
	}
	/**
	 * 查询未支付账单详情
	 * @param id 账单标识
	 * @return
	 */
	@RequestMapping(value = "/findBillDetailByWzfId", method = RequestMethod.GET)
	@ResponseBody
	public Tip findBillDetailByWzfId(long timestamp, String token, String id) throws  Exception {
		Tip tip = TokenUtils.verifyToken(timestamp, token);
		if(tip.getSuccess()) {
			HikBill  hikBill = new HikBill();
			hikBill= hikBillService.selectById(id);
			Tip hkTip =new Tip();
			hkTip = HikUtils.getParkingPaymentInfoRequestBO(hikBill.getPlateColor(),hikBill.getPlateNo());
			HikBill hikbill1 = (HikBill) hkTip.getData();
			if(hikbill1.getTotalCost()==null|| hikbill1.getTotalCost()==0){
				}else{
				hikBill.setNeedPay(hikbill1.getTotalCost());
				hikBill.setBillNo(hikbill1.getBillCode());
				hikBillService.updateById(hikBill);
			}

			tip = new Tip(hikBill);
		}
		return tip;
	}
	/**
	 * 查询账单详情
	 * @param id 账单标识
	 * @return
	 */
	@RequestMapping(value = "/findBillDetailById", method = RequestMethod.GET)
	@ResponseBody
	public Tip findBillDetailById(long timestamp, String token, String id)  {
		Tip tip = TokenUtils.verifyToken(timestamp, token);
		if(tip.getSuccess()) {
			tip = new Tip(hikBillService.selectById(id));
		}
		return tip;
	}

	/**
	 *
	 * @param timestamp
	 * @param token
	 * @param id
	 * @param userId
	 * @return
	 */
	@RequestMapping(value = "/payHikBillByBalance", method = RequestMethod.GET)
	@ResponseBody
	public Tip payHikBillByBalance(long timestamp, String token, String id, String userId) {
		Tip tip = TokenUtils.verifyToken(timestamp, token);
		if(tip.getSuccess()) {
			User user = userService.selectById(userId);
			if(user != null) {
				HikBill hb = hikBillService.selectById(id);
				if(hb != null) {
					BigDecimal money = CalculateUtils.divide(hb.getNeedPay(), 100);
					if(user.getWalletBalance().compareTo(money) != -1) {
						user.setWalletBalance(CalculateUtils.subtract(user.getWalletBalance(), money));
						try {
							userService.updateWalletBalanceById(user, "-", money, "支付车牌号码为" + hb.getPlateNo() + "的车辆于" + TimeUtils.getStringDateByMillionSeconds(hb.getOutTime()) + "在" + hb.getParkName() + "的停车费" + money + "元", 1, 3, hb.getId(), "余额支付停车费", "0",hb.getInDateTime(),hb.getOutDateTime(),hb.getParkTime(),hb.getPlateNo());
							hb.setPayStatus(1);
							hb.setPayMethod(1);
							hb.setUpdateTime(new Date());
							HikUtils.payParkingFee(hb.getBillNo(), hb.getNeedPay(), "11");
							hikBillService.updateById(hb);
							tip = new Tip("支付成功");
						} catch (Exception e) {
							e.printStackTrace();
							tip = new Tip(4, "系统异常，支付失败");
						}
					} else {
						tip = new Tip(3, "账户余额不足，请选择其他支付方式");
					}
				} else {
					tip = new Tip(2, "未查找该账单");
				}
			} else {
				tip = new Tip(1, "未查找该用户");
			}
		}
		return tip;
	}
	
	@RequestMapping(value = "/payHikBillByAlipay", method = RequestMethod.GET)
	@ResponseBody
	public Tip payHikBillByAlipay(long timestamp, String token, String id, String userId) {
		Tip tip = TokenUtils.verifyToken(timestamp, token);
		if(tip.getSuccess()) {
			User user = userService.selectById(userId);
			if(user != null) {
				HikBill hb = hikBillService.selectById(id);
				if(hb != null) {
					BigDecimal money = CalculateUtils.divide(hb.getNeedPay(), 100);
					String number = UUIDFactory.getBillNUmber(user.getPhone());
                    BillRecord billRecord = new BillRecord(UUIDFactory.getStringId(), number, money, new Date(), "支付车牌号码为" + hb.getPlateNo() + "的车辆于" + TimeUtils.getStringDateByMillionSeconds(hb.getOutTime()) + "在" + hb.getParkName() + "的停车费" + money + "元", "+", 0, 1, 3, hb.getId(), "支付宝支付停车", userId, user.getUserName(), user.getPhone(), user.getName(), user.getIdNumber(), "2",hb.getInDateTime(),hb.getOutDateTime(),hb.getParkTime(),hb.getPlateNo());

                    //实例化客户端
                    AlipayClient alipayClient = new DefaultAlipayClient("https://openapi.alipay.com/gateway.do", ShopInfo.APP_ID, ShopInfo.PRIVATE_KEY, "json", "utf-8", ShopInfo.PUBLIC_KEY, "RSA2");
                    //实例化具体API对应的request类,类名称和接口名称对应,当前调用接口名称：alipay.trade.app.pay
                    AlipayTradeAppPayRequest request = new AlipayTradeAppPayRequest();
                    //SDK已经封装掉了公共参数，这里只需要传入业务参数。以下方法为sdk的model入参方式(model和biz_content同时存在的情况下取biz_content)。
                    AlipayTradeAppPayModel model = new AlipayTradeAppPayModel();
                    model.setBody("");
                    model.setSubject("约慧夏都停车账单支付 ");
                    model.setOutTradeNo(number);
                    model.setTimeoutExpress("30m");
                    model.setTotalAmount(String.valueOf(money));
                    model.setProductCode("QUICK_MSECURITY_PAY");
                    request.setBizModel(model);
                    request.setNotifyUrl(ShopInfo.ALI_RECHARGE_NOTIFYURL);
                    try {
                        //这里和普通的接口调用不同，使用的是sdkExecute
                        AlipayTradeAppPayResponse response = alipayClient.sdkExecute(request);
                        //就是orderString 可以直接给客户端请求，无需再做处理。
                        billRecordService.insert(billRecord);
                        tip.setData(response.getBody());
                    } catch (AlipayApiException e) {
                        e.printStackTrace();
                        tip = new Tip(2, "充值数据异常");
                    } catch (Exception e) {
                        tip = new Tip(3, "系统异常，请刷新重试");
                    }
				} else {
					tip = new Tip(2, "未查找该账单");
				}
			} else {
				tip = new Tip(1, "未查找该用户");
			}
		}
		return tip;
	}
	
	@RequestMapping(value = "/payHikBillByWXPay", method = RequestMethod.GET)
	@ResponseBody
	public Tip payHikBillByWXPay(long timestamp, String token, String id, String userId, HttpServletRequest request) {
		Tip tip = TokenUtils.verifyToken(timestamp, token);
		if(tip.getSuccess()) {
			User user = userService.selectById(userId);
			if(user != null) {
				HikBill hb = hikBillService.selectById(id);
				if(hb != null) {
					BigDecimal money = CalculateUtils.divide(hb.getNeedPay(), 100);
					String number = UUIDFactory.getBillNUmber(user.getPhone());
                    BillRecord billRecord = new BillRecord(UUIDFactory.getStringId(), number, money, new Date(), "支付车牌号码为" + hb.getPlateNo() + "的车辆于" + TimeUtils.getStringDateByMillionSeconds(hb.getOutTime()) + "在" + hb.getParkName() + "的停车费" + money + "元", "+", 0, 1, 3, hb.getId(), "微信支付停车", userId, user.getUserName(), user.getPhone(), user.getName(), user.getIdNumber(), "3",hb.getInDateTime(),hb.getOutDateTime(),hb.getParkTime(),hb.getPlateNo());
                    
                    PaymaxConfig config = new PaymaxConfig(ShopInfo.WX_APPID, ShopInfo.WX_MCHID, ShopInfo.WX_KEY, ShopInfo.WX_RECHARGE_NOTIFYURL, ShopInfo.WX_TRADETYPE_APP, ShopInfo.WX_URL, ShopInfo.POST);
                    
                    Unifiedorder unifiedorder = new Unifiedorder();
                    unifiedorder.setAppid(config.getAppId());
            		unifiedorder.setMch_id(config.getMchId());
            		unifiedorder.setNonce_str(RandCharsUtils.getRandomString(16));
            		unifiedorder.setBody(billRecord.getContent());
            		unifiedorder.setDetail(billRecord.getIntro());
            		unifiedorder.setAttach("");
            		unifiedorder.setOut_trade_no(number);
            		unifiedorder.setTotal_fee(CalculateUtils.multiply(money, 100).intValue());
            		unifiedorder.setSpbill_create_ip(request.getRemoteAddr());
            		unifiedorder.setTime_start(RandCharsUtils.timeStart());
            		unifiedorder.setTime_expire(RandCharsUtils.timeExpire());
            		unifiedorder.setNotify_url(config.getNotifyUrl());
            		unifiedorder.setTrade_type(config.getTradeType());
                	tip = new WXPay().payByApp(unifiedorder, config);
                	if(tip.getSuccess()) {
                		try {
        					billRecordService.insert(billRecord);
        				} catch (Exception e) {
        					e.printStackTrace();
        					logger.info("编号为：" + number + "的订单保存失败");
        				}
                	}
				} else {
					tip = new Tip(2, "未查找该账单");
				}
			} else {
				tip = new Tip(1, "未查找该用户");
			}
		}
		return tip;
	}

//	@Scheduled(cron = "0/5 * * * * ?")
	public void dumpBill(){
		Long count = hikBillService.countNoPayBill();
		try {
			hikBillService.deleteNoPay();
			logger.info("成功清理了"+count+"条未支付订单");
		} catch (Exception e) {
//			e.printStackTrace();
			logger.info("清理未支付订单失败");
		}

	}

    //---------------------------- property -------------------------------

    @Resource
    private HikBillService hikBillService;

	@Resource
	private UserService userService;
	
	@Resource
	private BillRecordService billRecordService;

}
